package com.ssy.lingxi.member.merchant.serviceimpl.base;

import com.ssy.lingxi.common.constant.basic.EnableDisableStatus;
import com.ssy.lingxi.common.response.PageData;
import com.ssy.lingxi.common.response.ResponseCode;
import com.ssy.lingxi.common.response.Wrapper;
import com.ssy.lingxi.member.merchant.entity.MemberDO;
import com.ssy.lingxi.member.merchant.entity.MemberOrganizationDO;
import com.ssy.lingxi.member.merchant.entity.MemberUserDO;
import com.ssy.lingxi.member.merchant.model.constant.MemberUserAuthTypeEnum;
import com.ssy.lingxi.member.merchant.model.vo.basic.response.UserQueryVO;
import com.ssy.lingxi.member.merchant.repository.MemberRepository;
import com.ssy.lingxi.member.merchant.repository.MemberUserRepository;
import com.ssy.lingxi.member.merchant.service.base.IBaseUserDetailService;
import com.ssy.lingxi.member.merchant.utils.MemberOrganizationUtil;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import javax.persistence.criteria.Join;
import javax.persistence.criteria.JoinType;
import javax.persistence.criteria.Predicate;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * (内部)用户详细信息查询服务实现类
 * @author 万宁
 * @version 2.0.0
 * @date 2021-05-27
 */
@Service
public class BaseUserDetailServiceImpl implements IBaseUserDetailService {
    @Resource
    private MemberRepository memberRepository;

    @Resource
    private MemberUserRepository memberUserRepository;

    /**
     * 分页查询用户列表
     *
     * @param memberId 会员Id
     * @param name     用户姓名
     * @param orgName  组织机构名称
     * @param jobTitle 职位
     * @param current  当前页
     * @param pageSize 每页行数
     * @param includeSuperAdmin 是否包含会员超级管理员
     * @return 查询结果
     */
    @Override
    public Wrapper<PageData<UserQueryVO>> pageUsers(Long memberId, String name, String orgName, String jobTitle, int current, int pageSize, boolean includeSuperAdmin) {
        MemberDO memberDO = memberRepository.findById(memberId).orElse(null);
        if(memberDO == null) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_DOES_NOT_EXIST);
        }

        Pageable page = PageRequest.of(current - 1, pageSize, Sort.by("id").ascending());
        Specification<MemberUserDO> specification = (Specification<MemberUserDO>) (root, query, criteriaBuilder) -> {
            List<Predicate> list = new ArrayList<>();

            Join<MemberUserDO, MemberDO> memberJoin = root.join("member", JoinType.LEFT);
            list.add(criteriaBuilder.equal(memberJoin.get("id").as(Long.class), memberId));

            list.add(criteriaBuilder.equal(root.get("status").as(Integer.class), EnableDisableStatus.ENABLE.getCode()));

            if(!includeSuperAdmin) {
                list.add(criteriaBuilder.equal(root.get("typeEnum").as(Integer.class), MemberUserAuthTypeEnum.NORMAL.getCode()));
            }

            if(StringUtils.hasLength(name)) {
                list.add(criteriaBuilder.like(root.get("name").as(String.class), "%" + name.trim() + "%"));
            }

            if(StringUtils.hasLength(jobTitle)) {
                list.add(criteriaBuilder.like(root.get("jobTitle").as(String.class), "%" + jobTitle.trim() + "%"));
            }

            if(StringUtils.hasLength(orgName)) {
                Join<MemberUserDO, MemberOrganizationDO> orgJoin = root.join("org", JoinType.LEFT);
                list.add(criteriaBuilder.like(orgJoin.get("title").as(String.class), "%" + orgName + "%"));
            }

            Predicate[] p = new Predicate[list.size()];
            return criteriaBuilder.and(list.toArray(p));
        };

        Page<MemberUserDO> pageList = memberUserRepository.findAll(specification, page);

        //将会员组织机构全部查出来，用于拼接组织机构名称
        List<MemberOrganizationDO> orgList = new ArrayList<>(memberDO.getOrgs());

        return Wrapper.success(new PageData<>(pageList.getTotalElements(), pageList.getContent().stream().map(memberUserDO -> {
            UserQueryVO queryVO = new UserQueryVO();
            queryVO.setUserId(memberUserDO.getId());
            queryVO.setName(memberUserDO.getName());
            queryVO.setPhone(memberUserDO.getPhone());
            queryVO.setJobTitle(StringUtils.hasLength(memberUserDO.getJobTitle()) ? memberUserDO.getJobTitle() : "");
            queryVO.setOrgName(MemberOrganizationUtil.joinTitleToString(memberUserDO.getOrg() == null ? 0L : memberUserDO.getOrg().getId(), orgList));
            return queryVO;
        }).collect(Collectors.toList())));
    }

    /**
     * 分页查询用户列表
     * @param memberId          会员Id
     * @param keyword           用户姓名/组织机构名称
     * @param current           当前页
     * @param pageSize          每页行数
     * @param includeSuperAdmin 是否包含会员超级管理员
     * @return 查询结果
     */
    @Override
    public Wrapper<PageData<UserQueryVO>> pageUsers(Long memberId, String keyword, int current, int pageSize, boolean includeSuperAdmin) {
        MemberDO memberDO = memberRepository.findById(memberId).orElse(null);
        if(memberDO == null) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_DOES_NOT_EXIST);
        }

        Pageable page = PageRequest.of(current - 1, pageSize, Sort.by("id").ascending());
        Specification<MemberUserDO> specification = (root, query, criteriaBuilder) -> {
            List<Predicate> list = new ArrayList<>();

            Join<MemberUserDO, MemberDO> memberJoin = root.join("member", JoinType.LEFT);
            list.add(criteriaBuilder.equal(memberJoin.get("id").as(Long.class), memberId));

            list.add(criteriaBuilder.equal(root.get("status").as(Integer.class), EnableDisableStatus.ENABLE.getCode()));

            if(!includeSuperAdmin) {
                list.add(criteriaBuilder.equal(root.get("typeEnum").as(Integer.class), MemberUserAuthTypeEnum.NORMAL.getCode()));
            }

            if (StringUtils.hasLength(keyword)) {
                Join<MemberUserDO, MemberOrganizationDO> orgJoin = root.join("org", JoinType.LEFT);
                list.add(criteriaBuilder.or(
                        criteriaBuilder.like(root.get("name").as(String.class), "%" + keyword.trim() + "%"),
                        criteriaBuilder.like(orgJoin.get("title").as(String.class), "%" + keyword + "%")));
            }

            Predicate[] p = new Predicate[list.size()];
            return criteriaBuilder.and(list.toArray(p));
        };

        Page<MemberUserDO> pageList = memberUserRepository.findAll(specification, page);

        //将会员组织机构全部查出来，用于拼接组织机构名称
        List<MemberOrganizationDO> orgList = new ArrayList<>(memberDO.getOrgs());

        return Wrapper.success(new PageData<>(pageList.getTotalElements(), pageList.getContent().stream().map(memberUserDO -> {
            UserQueryVO queryVO = new UserQueryVO();
            queryVO.setUserId(memberUserDO.getId());
            queryVO.setName(memberUserDO.getName());
            queryVO.setPhone(memberUserDO.getPhone());
            queryVO.setJobTitle(StringUtils.hasLength(memberUserDO.getJobTitle()) ? memberUserDO.getJobTitle() : "");
            queryVO.setOrgName(MemberOrganizationUtil.joinTitleToString(memberUserDO.getOrg() == null ? 0L : memberUserDO.getOrg().getId(), orgList));
            return queryVO;
        }).collect(Collectors.toList())));
    }
}
